package com.proxy.router;

import com.proxy.parser.result.ShowDatabasesResult;
import com.proxy.parser.result.ShowTablesResult;
import com.proxy.parser.result.ShowVariantsResult;
import com.proxy.parser.tree.sql.ast.SQLStatement;
import com.proxy.parser.tree.sql.ast.statement.SQLSelectStatement;
import com.proxy.parser.tree.sql.ast.statement.SQLShowTablesStatement;
import com.proxy.parser.tree.sql.ast.statement.SQLUseStatement;
import com.proxy.parser.tree.sql.dialect.mysql.ast.statement.*;
import com.proxy.parser.tree.sql.dialect.mysql.parser.MySqlStatementParser;
import com.proxy.parser.tree.sql.dialect.mysql.visitor.MySqlSchemaStatVisitor;
import com.proxy.parser.tree.sql.parser.SQLStatementParser;
import com.proxy.router.interceptor.*;

import java.util.Collections;
import java.util.List;

/**
 * Created by liufish on 16/11/1.
 */
public class SQLRouteEngine {


    /**
     * SQL路由.
     *
     * @param sql
     * @param schema
     */
    public SQLRouteResult route(String sql,String schema)  {
       return this.route(sql,schema, Collections.emptyList());
    }


    /**
     * SQL路由.
     *
     * @param sql 逻辑SQL
     */
    public SQLRouteResult route(String sql, String schema, List<Object> parameters)  {

        SQLRouteResult result = new SQLRouteResult(sql,schema);

        SQLStatementParser parser = new MySqlStatementParser(sql);
        SQLStatement sqlStatement = parser.parseStatement();
        MySqlSchemaStatVisitor visitor = new MySqlSchemaStatVisitor();
        sqlStatement.accept(visitor);

        Interceptor interceptor = null;

        do {

            /**
             * select
             */
            if(sqlStatement instanceof SQLSelectStatement){
                interceptor =  new SelectInterceptor();
                break;
            }

            /**
             * show
             */
            if(sqlStatement instanceof MySqlShowDatabasesStatement){
                result.setExtra(new ShowDatabasesResult());
                break;
            }

            if(sqlStatement instanceof MySqlShowVariantsStatement){
                result.setExtra(new ShowVariantsResult());
                break;
            }

            if(sqlStatement instanceof SQLShowTablesStatement){
                result.setExtra(new ShowTablesResult());
                break;
            }

            if(sqlStatement instanceof MySqlShowCreateTableStatement){
                interceptor = new ShowCreateTableInterceptor();
                break;
            }

            if(sqlStatement instanceof MySqlShowColumnsStatement){

                break;
            }

            if(sqlStatement instanceof MySqlShowIndexesStatement){

                break;
            }






            /**
             * for set
             */
            if(sqlStatement instanceof MySqlSetNamesStatement){
                interceptor = new SetNamesInterceptor();
                break;
            }
            if(sqlStatement instanceof MySqlSetTransactionStatement){
                interceptor = new SetTransactionInterceptor();
                break;
            }

            //set autocommit=1



            /**
             * use
             */
            if (sqlStatement instanceof SQLUseStatement) {
                interceptor = new SQLUseStatementInterceptor();
                break;
            }



        }while (false);






        if(interceptor != null){
            interceptor.before(result,null);
            interceptor.routing(result,sqlStatement,visitor,parameters);
            interceptor.after(result,null);
        }
        return result;


    }

}
